/***************************************************************************
 创建者: hualei
 开始时间: 2018.9.10
 copyright: (C) 华友高科
 修改说明: (每次有修改就添加一条，带有 修改人，修改时间，修改描述)
 example (1) hualei 2018.5.8 类的具体实现代码编写

 ***************************************************************************
 *  @file maganeticsensor.h
 *  功能: 磁传感器的设置和数据获取
 *
 *                                                                         *
 ***************************************************************************/
#ifndef MAGANETICSENSOR_H
#define MAGANETICSENSOR_H

#include <QString>
#include "modbus.h"
#include <QMap>
#include <QTimer>
#include <qobject.h>
#include <QMutex>
#include <QList>
#include "GeneralDefine.h"

#define D_REGISTER_NUMBER                   (8)              // 寄存器数量
#define D_TRIGGER_PARAMETER_REGISTER        (0x31)           // 触发参数寄存器地址
#define D_BAUD_REGISTER                     (0x2c)           // 通信波特率寄存器地址
#define D_POSITION_REGISTER_FIRST_ADDRESS   (0x20)           // 位置寄存器第一地址
#define D_MODBUS_ID_ADDRESSS                (0x33)           // Modbus ID寄存器地址
#define D_TEMPTURE_REGISTER_ADDRESS         (0x29)           // 内部温度寄存器地址

/**
 * @brief The MaganeticDevice struct        磁传感器设置总线配置
 */
struct MaganeticDevice
{
    /**
     * @brief ModbusType            Modbus总线类型
     */
    int ModbusType;
    /**
     * @brief serialDeviceName      串口设备文件名
     */
    QString serialDeviceName;

    /**
     * @brief baud                  波特率
     */
    int baud;
    /**
     * @brief parity                校验位
     */
    QString parity;
    /**
     * @brief data_bits             数据位
     */
    int data_bits;
    /**
     * @brief stop_bits             停止位
     */
    int stop_bits;

    /**
     * @brief updatePeriod          更新周期
     */
    int updatePeriod;

};

//enum E_MODBUS_TYPE
//{
//    E_MODBUS_TYPE_RTU=1,
//    E_MODBUS_TYPE_TCP=2
//};

//enum E_VENDOR_ID
//{
//    E_VENDOR_ID_DE_MO_TE = 1,

//};

/**
 * @brief The MaganeticDetectData struct        磁传感器检查数据
 */
struct MaganeticDetectData
{
    /**
     * @brief positionValue        检测磁条位置数值
     */
    double positionValue;
};

/**
 * @brief The DeviceName struct         磁传感器设备
 */
struct DeviceName
{
    /**
     * @brief deviceVendorId            厂商ID
     */
    int deviceVendorId;

    /**
     * @brief deviceId                  设备ID
     */
    int deviceId;
};

/**
 * @brief The MaganeticSensor class     磁传感器类,设置和检测磁条位置数据
 */
class MaganeticSensor:public QObject
{
    Q_OBJECT
public:

    /**
     * @brief MaganeticSensor       构造函数
     * @param configFilePath        磁传感器配置文件路径
     */
    MaganeticSensor(QString configFilePath);

public:
    int setDebugFlag(int debugFlagIn);
    /**
     * @brief getSensorPositionValue        获取磁传感器位置数据
     * @param deviceIdIn                    磁传感器设备ID
     * @param valueOut
     * @return 1=success, 0= 没有灯亮，　－１＝通讯失败
     */
    int getSensorPositionValue(int deviceIdIn, double &valueOut);

    /**
     * @brief isInitialStatus       配置文件初始化状态
     * @return                      false:失败  true:成功
     */
    bool isInitialStatus();

    /**
     * @brief setSensorDeviceId     设置传感器设备ID
     * @param primaryIdIn           原ID
     * @param targetIdIn            目标ID
     * @return                      success: 1  fail: -1/0
     */
    int setSensorDeviceId(int primaryIdIn, int targetIdIn);

    /**
     * @brief checkModbusMaster     检查主机是否有效
     * @return                      success: 1  fail: -1
     */
    int checkModbusMaster();

    /**
     * @brief connectPort           连接串口
     * @return                      success: 1  fail: <0
     */
    int connectPort();

private:
    /**
     * @brief initialSensorByConfigFile     初始化磁传感器配置文件
     * @param configFilePath                磁传感器配置文件路径
     * @return                              success: 1  fail: -1
     */
    int initialSensorByConfigFile(QString configFilePath);

    /**
     * @brief getDeviceVendorId_1_DetectValue       获取厂商ID编号1的探测数据
     * @return                              success: 1  fail: -1
     */
    int getDeviceVendorId_1_DetectValue();

    /**
     * @brief positionDataProcess            对探测到的位置数据处理
     * @param positionDataList               探测数据
     * @return                               success: (double)positionValue  fail: -1
     */
    double positionDataProcess(QList<int> positionDataList);

    /**
     * @brief getTriggerFactorValue         获取磁传感器触发系数
     * @return                              失败:-1  成功:返回触发系数数值
     */
    int getTriggerFactorValue();

private slots:

    /**
     * @brief getPositionData               获取位置数据槽函数
     */
    void getPositionData();

private:
    /**
     * @brief modbusMaster                  modbus主机对象
     */
    modbus_t *modbusMaster;

    /**
     * @brief maganeticCurrentSlaveId       磁传感器当前从设备ID
     */
    int maganeticCurrentSlaveId;

    /**
     * @brief isInitialConfigOk             配置文件初始化状态
     */
    bool isInitialConfigOk;

    /**
     * @brief isConnectPortOk               总线连接状态
     */
    bool isConnectPortOk;

    /**
     * @brief maganeticDevice               磁传感器设置总线配置
     */
    MaganeticDevice *maganeticDevice;

    /**
     * @brief deviceNameMap                 磁传感器设备
     */
    QMap <int, DeviceName > deviceNameMap;

    /**
     * @brief itDeviceName                  磁传感器设备迭代器对象
     */
    QMap <int, DeviceName >::iterator itDeviceName;

    /**
     * @brief positionDataMap               保存探测数据容器
     */
    QMap <int, double> positionDataMap;

    /**
     * @brief mutex                         mutex锁
     */
    QMutex mutex;

    /**
     * @brief timer                         定时器
     */
    QTimer timer;

    /**
     * @brief triggerParameter              磁传感器触发系数
     */
    int triggerParameter;

    /**
     * @brief isCommunicateOk               通信状态
     */
    bool isCommunicateOk;

    /**
     * @brief isMaganeticOutOfRange         探测数据是否超出范围
     */
    bool isMaganeticOutOfRange;

    int debugFlag;
};

#endif // MAGANETICSENSOR_H
